#ifdef HIGHPRECISION
	precision highp float;
#else
	precision mediump float;
#endif

#include "LightHelper.glsl";

#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)
	uniform vec3 u_MaterialDiffuse;
	uniform vec4 u_MaterialSpecular;
	uniform vec3 u_CameraPos;
	varying vec3 v_Normal;
	varying vec3 v_PositionWorld;
#endif

#ifdef FOG
	uniform float u_FogStart;
	uniform float u_FogRange;
	uniform vec3 u_FogColor;
#endif


#ifdef DIRECTIONLIGHT
	uniform DirectionLight u_DirectionLight;
#endif

#ifdef POINTLIGHT
	uniform PointLight u_PointLight;
#endif

#ifdef SPOTLIGHT
	uniform SpotLight u_SpotLight;
#endif

uniform vec3 u_AmbientColor;

#include "ShadowHelper.glsl"
#ifdef RECEIVESHADOW
	#if defined(SHADOWMAP_PSSM2)||defined(SHADOWMAP_PSSM3)
	uniform mat4 u_lightShadowVP[4];
	#endif
	#ifdef SHADOWMAP_PSSM1 
	varying vec4 v_lightMVPPos;
	#endif
#endif
varying float v_posViewZ;


uniform sampler2D u_SplatAlphaTexture;

uniform sampler2D u_DiffuseTexture1;
uniform sampler2D u_DiffuseTexture2;
uniform sampler2D u_DiffuseTexture3;
uniform sampler2D u_DiffuseTexture4;
uniform sampler2D u_DiffuseTexture5;

uniform vec4 u_DiffuseScaleOffset1;
uniform vec4 u_DiffuseScaleOffset2;
uniform vec4 u_DiffuseScaleOffset3;
uniform vec4 u_DiffuseScaleOffset4;
uniform vec4 u_DiffuseScaleOffset5;

varying vec2 v_Texcoord0;

uniform vec3 u_MaterialAmbient;
uniform vec4 u_MaterialAlbedo;

#ifdef LIGHTMAP
	uniform sampler2D u_LightMap;
	varying vec2 v_LightMapUV;
#endif

void main()
{
	#ifdef ExtendTerrain_DETAIL_NUM1
		vec4 splatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);
		vec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);
		gl_FragColor.xyz = color1.xyz * splatAlpha.r;
	#endif
	#ifdef ExtendTerrain_DETAIL_NUM2
		vec4 splatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);
		vec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);
		vec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);
		gl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * (1.0 - splatAlpha.r);
	#endif
	#ifdef ExtendTerrain_DETAIL_NUM3
		vec4 splatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);
		vec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);
		vec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);
		vec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);
		gl_FragColor.xyz = color1.xyz * splatAlpha.r  + color2.xyz * splatAlpha.g + color3.xyz * (1.0 - splatAlpha.r - splatAlpha.g);
	#endif
	#ifdef ExtendTerrain_DETAIL_NUM4
		vec4 splatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);
		vec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);
		vec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);
		vec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);
		vec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);
		gl_FragColor.xyz = color1.xyz * splatAlpha.r  + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b);
	#endif
	#ifdef ExtendTerrain_DETAIL_NUM5
		vec4 splatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);
		vec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);
		vec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);
		vec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);
		vec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);
		vec4 color5 = texture2D(u_DiffuseTexture5, v_Texcoord0 * u_DiffuseScaleOffset5.xy);
		gl_FragColor.xyz = color1.xyz * splatAlpha.r  + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * splatAlpha.a + color5.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b - splatAlpha.a);
	#endif
		gl_FragColor.w = splatAlpha.a;
		
#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)
    vec3 normal = v_Normal;
	vec3 diffuse = vec3(0.0);
	vec3 ambient = vec3(0.0);
	vec3 specular= vec3(0.0);
	vec3 dif, amb, spe;
#endif

#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)
	vec3 toEye;
	#ifdef FOG
		toEye=u_CameraPos-v_PositionWorld;
		float toEyeLength=length(toEye);
		toEye/=toEyeLength;
	#else
		toEye=normalize(u_CameraPos-v_PositionWorld);
	#endif
#endif

#ifdef DIRECTIONLIGHT
	computeDirectionLight(u_MaterialDiffuse,u_MaterialAmbient,u_MaterialSpecular,u_DirectionLight,u_AmbientColor,normal,toEye, dif, amb, spe);
	diffuse+=dif;
	ambient+=amb;
	specular+=spe;
#endif
 
#ifdef POINTLIGHT
	computePointLight(u_MaterialDiffuse,u_MaterialAmbient,u_MaterialSpecular,u_PointLight,u_AmbientColor,v_PositionWorld,normal,toEye, dif, amb, spe);
	diffuse+=dif;
	ambient+=amb;
	specular+=spe;
#endif

#ifdef SPOTLIGHT
	ComputeSpotLight(u_MaterialDiffuse,u_MaterialAmbient,u_MaterialSpecular,u_SpotLight,u_AmbientColor,v_PositionWorld,normal,toEye, dif, amb, spe);
	diffuse+=dif;
	ambient+=amb;
	specular+=spe;
#endif

#ifdef RECEIVESHADOW
	float shadowValue = 1.0;
	#ifdef SHADOWMAP_PSSM3
		shadowValue = getShadowPSSM3( u_shadowMap1,u_shadowMap2,u_shadowMap3,u_lightShadowVP,u_shadowPSSMDistance,u_shadowPCFoffset,v_PositionWorld,v_posViewZ,0.001);
	#endif
	#ifdef SHADOWMAP_PSSM2
		shadowValue = getShadowPSSM2( u_shadowMap1,u_shadowMap2,u_lightShadowVP,u_shadowPSSMDistance,u_shadowPCFoffset,v_PositionWorld,v_posViewZ,0.001);
	#endif 
	#ifdef SHADOWMAP_PSSM1
		shadowValue = getShadowPSSM1( u_shadowMap1,v_lightMVPPos,u_shadowPSSMDistance,u_shadowPCFoffset,v_posViewZ,0.001);
	#endif
#endif

#ifdef LIGHTMAP
	#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)
		gl_FragColor.rgb=gl_FragColor.rgb*(u_MaterialAmbient + texture2D(u_LightMap, v_LightMapUV).rgb);
	#else
		#if defined(RECEIVESHADOW)		
			gl_FragColor.rgb=gl_FragColor.rgb*(u_MaterialAmbient+texture2D(u_LightMap, v_LightMapUV).rgb * shadowValue);
			//vec3 tColor= u_MaterialAmbient + texture2D(u_LightMap, v_LightMapUV).rgb * shadowValue + mix(vec3(0.15,0.15,0.15),vec3(0.0),shadowValue);
			//gl_FragColor.rgb*=tColor;
		#else
			gl_FragColor.rgb=gl_FragColor.rgb*(u_MaterialAmbient + texture2D(u_LightMap, v_LightMapUV).rgb);
		#endif
	#endif
#endif

gl_FragColor=gl_FragColor*u_MaterialAlbedo;

#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)
	#ifdef RECEIVESHADOW
		gl_FragColor = vec4( gl_FragColor.rgb*(ambient + diffuse*shadowValue) + specular * shadowValue,gl_FragColor.a);
	#else
		gl_FragColor =vec4( gl_FragColor.rgb*(ambient + diffuse) + specular, gl_FragColor.a);
	#endif
#endif

#ifdef FOG
	float lerpFact=clamp((toEyeLength-u_FogStart)/u_FogRange,0.0,1.0);
	gl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);
#endif
}





